/*
 * @Author: yangzonglong
 * @Date: 2021-05-07 13:54:51
 * @version: v1.0.0
 * @Descripttion:
 * @LastEditors: yangzonglong
 * @LastEditTime: 2023-02-15 14:52:17
 * @Auditor:
 */
import React, { useState, useCallback, useRef, useEffect } from 'react';
import { PageHeader, Formx, FormxControlTypes, Button, units, history, Tabs } from '@library';
import { FormxRefProps } from '@library/components/formx/interface';
import Qs from 'query-string';
import { setQuitInquiry } from '@library/app/history';
import { Button as AntdButton, Dropdown, Modal } from 'antd';
import { exportJson } from '../../../utils/exportJson';
import FormDesign, { FormDesignRefProps } from './../../../components/formDesign/FormDesign';
import { FormProps } from './../../../interface';
import { saveForm, getForm } from './../api';
import ImportJson from './_ImportJson';
import style from './../style.module.scss';
import i18n from "@library/app/i18n";

const required = true;
const t = window.$app.t;

const formEngine = [
  { value: 'LFORM', label: 'LFORM' },
  { value: 'GFORM', label: 'GFORM' },
];

const formItems = [
  { name: 'formEngine', required, type: FormxControlTypes.SELECT, options: { dataSource: formEngine } },
  { name: 'formName', required },
  { name: 'formEnName' },
  { name: 'breadCrumb' },
  { name: 'formDesc', required },
  {
    name: 'categoryCode',
    label: t('category'),
    type: FormxControlTypes.SELECT,
    initialValue: 'workflow',
    options: {
      url: '/bk/api/console/ServiceModule/find',
      fieldNames: { label: i18n.language === 'en' ? 'moduleEnName' : 'moduleName', value: 'moduleCode' }
    }
  },

  { name: 'firstLevelEntry', type: FormxControlTypes.CHECKBOX },
  { name: 'auditFlag', type: FormxControlTypes.CHECKBOX, ghost: '!{{firstLevelEntry}}' },
  {
    name: 'workflowNumber',
    label: t('workflowName_'),
    type: FormxControlTypes.SELECT,
    ghost: "!({{firstLevelEntry}} && {{auditFlag}})",
    required: true,
    options: {
      url: '/bk/api/workflow/WorkFlowHead/find',
      fieldNames: { label: 'name', value: 'workflowNumber' },
      query: { where: { status: "20" } }
    }
  },
  { name: 'functionCode', required, ghost: '!{{firstLevelEntry}}' },
  {
    name: 'functionGroup',
    required,
    type: FormxControlTypes.SELECT,
    ghost: '!{{firstLevelEntry}}',
    options: {
      url: '/bk/api/console/ConsoleCode/findOne',
      extra: ['codeDesc:functionGroupDesc'],
      query: {
        where: { code: "FUNCTION_GROUP" },
        include: { all: true },
      },
      fieldNames: { label: 'codeDesc', value: 'codeValue' },
      rtnDataAfter: (res: any) => {
        return res.ConsoleCodeValues || [];
      }
    }
  },
  {
    name: 'functionOrder', required, ghost: '!{{firstLevelEntry}}'
  },
  {
    name: 'printScale', type: FormxControlTypes.NUMBER, options: {
      max: 100,
      min: 10,
      integer: true
    }
  },
  { name: 'createdAt', disabled: true },
  { name: 'enviromentConfig', type: FormxControlTypes.TEXT_AREA },
];

const initialValues = { firstLevelEntry: false, auditFlag: false };

const tabsData = [
  { id: 'base', label: t('baseInfo') },
  { id: 'form', label: t('formDetails') }
];

export default () => {
  const isChange = useRef(false);
  const query = Qs.parseUrl(window.location.href).query;
  const formDesignRef = useRef<FormDesignRefProps>(null);
  const formxRef = useRef<FormxRefProps>(null);
  const [formEngine, setFormEngine] = useState('GFORM');
  const [details, setDetails] = useState<FormProps>(initialValues as any);
  const [current, setCurrent] = useState(tabsData[0].id);

  useEffect(() => {
    if (query.id)
      getForm(query.id as string).then((details) => {
        if (typeof details !== 'boolean') {
          setDetails(details);
          setFormEngine(details.formEngine);
        }
      });
  }, [query.id]);

  useEffect(() => {
    setQuitInquiry(() => {
      return !isChange.current;
    });
    return () => setQuitInquiry();
  }, []);

  const onValuesChange = useCallback(
    (value, allValue) => {
      const changeKey = Object.keys(value)[0];

      isChange.current = true;

      if (changeKey === 'formEngine') {
        setFormEngine(allValue.formEngine);
        if (details.content) setDetails({ ...details, content: '' });
      } else if (changeKey === 'auditFlag') {
        if (value.auditFlag === false) {
          formxRef.current?.setFieldsValue({
            workflowNumber: ''
          });
        }
      } else if (changeKey === 'firstLevelEntry') {
        formxRef.current?.setFieldsValue({
          auditFlag: false,
          workflowNumber: '',
          functionOrder: '',
          functionGroup: '',
          functionCode: '',
        });
      }


    },
    [details]
  );

  const check = useCallback(async () => {
    const formData = await formxRef.current?.validateFields();
    if (!formData) return;

    formDesignRef.current?.getDesign(formData.formName);
  }, []);

  const onSubmit = useCallback(async (content) => {

    const fn = async () => {
      const formData = await formxRef.current?.validateFields();

      const mergeData = { ...formData, content };

      let contentData = content ? JSON.parse(content) : {};

      contentData = contentData.list?.map((item: any) => {
        return {
          key: item.options?.formItemProps?.name || item.id,
          title: item.options?.formItemProps?.label || item.options?.title,
          type: item.type
        };
      }, {});

      mergeData.contentData = JSON.stringify(contentData);
      mergeData.printScale = mergeData.printScale || 100;

      if (!mergeData.auditFlag) {
        mergeData.workflowNumber = '';
      }

      const result = await saveForm(mergeData as any);

      if (result) {
        isChange.current = false;
        setDetails(prev => ({ ...prev, ...result }));
        units.message.success();
        history.replace('/form/details?id=' + result.id);
      }
    };

    if (details.id) {
      const res: any = await getForm(details.id as string, ['updatedAt']);
      if (res?.updatedAt !== details.updatedAt) {
        Modal.confirm({
          title: t('form_tips'),
          cancelText: t('cancel'),
          okText: t('ok'),
          onOk() {
            fn();
          },
          onCancel() {

          }
        });
      } else {
        fn();
      }
    } else {
      fn();
    }


  }, [details.updatedAt, details.id]);

  const exportJsonFn = useCallback(() => {
    formDesignRef.current?.getDesign('GFORM', (design: string) => {
      exportJson('gform.json', design);
    }, true);
  }, []);

  const initGform = useCallback((str: string) => {
    formDesignRef.current?.syncGform(str ? JSON.parse(str).list : []);
  }, []);

  const preview = useCallback(() => {
    // formDesignRef.current?.preview()
    window.open(`${window.location.href.includes('http://localhost') ? '' : '/core/app'}/workflow/form/details/preview?id=` + query.id);
  }, [query.id]);

  const formDesignChange = useCallback(() => (isChange.current = true), []);

  // 对于echarts图表 全局挂载chartsResize方法 撑满区域
  useEffect(() => {
    if (current === tabsData[1].id) {
      (window as any).chartsResize?.forEach((element: Function) => {
        element?.();
      });
    }
  }, [current]);

  // 销毁挂载的chartsResize方法
  useEffect(() => {
    return () => {
      (window as any).chartsResize = null;
    };
  }, []);


  return (
    <>
      <PageHeader
        extra={
          <>
            {formEngine === 'GFORM' && (
              <AntdButton.Group>
                <Button.View disabled={!query?.id} onClick={preview} type="default">
                  {t('preview')}
                </Button.View>
                <Button.Download onClick={exportJsonFn} type="default">
                  {t('export')}
                </Button.Download>

                <Dropdown overlay={<ImportJson onOk={initGform} />}>
                  <AntdButton>...</AntdButton>
                </Dropdown>
              </AntdButton.Group>
            )}
            <span className="wingBlank" />
            <Button.Save onClick={check} />
          </>
        }
      />
      <div className='common-block common-flex'>
        <Tabs mode='tabs' tabs={tabsData} curTabId={current} onChange={setCurrent} />
        <div hidden={current === tabsData[1].id}>
          <Formx initialValues={details} ref={formxRef} formItems={formItems} onValuesChange={onValuesChange} />
        </div>
        <div hidden={current === tabsData[0].id} className='common-flex'>
          {formEngine && (
            <div className={style.formDesign}>
              <FormDesign
                onChange={formDesignChange}
                formInfo={{ formDesc: details.formDesc, formName: details.formName }}
                content={details.content}
                ref={formDesignRef}
                onOk={onSubmit}
                formEngine={formEngine}
              />
            </div>
          )}
        </div>
      </div>
    </>
  );
};
